package org.NooLab.texxplugg.tika;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

import java.net.URL;
import java.util.ArrayList;
import java.util.Map;


import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.tika.config.TikaConfig;
import org.apache.tika.detect.DefaultDetector;
import org.apache.tika.detect.Detector;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;



public class TikaExtraction{

	private static final String CONSOLE_APPENDER_NAME = "CONSOLE";
	private static final Logger LOG = Logger.getLogger(TikaExtraction.class.getPackage().getName());
	private final static Logger log1 = Logger.getLogger( org.apache.tika.parser.Parser.class ); 
	private final static Logger log2 = Logger.getLogger( org.apache.tika.parser.AutoDetectParser.class ); 
	
	OutputStream outputstream;

	ParseContext context;

	Detector detector;

	protected Parser parser;

	protected Metadata metadata;
	protected String mimeType="";
	
	private String extractedText = "";
	private String fileSourceUrl = "";
	
	// ========================================================================
	public TikaExtraction(String documentsource) {

		fileSourceUrl = documentsource ;
		
		context = new ParseContext();

		detector = new DefaultDetector();

		parser = new AutoDetectParser(detector);

		Logger  rootLogger;  
		
	 
		 
		rootLogger = Logger.getRootLogger();
		rootLogger.setLevel(Level.ERROR) ;
		// rootLogger.removeAllAppenders() ;
		
		// System.out.println("rootLogger "+rootLogger.toString());
		
		context.set(Parser.class, parser);

		outputstream = new ByteArrayOutputStream();

		metadata = new Metadata();

	}
	
	
	private void process(String filename) { // throws Exception 

		URL url;
		int treatment = 1;
		int err=1;
		
		try{
		

			File file = new File(filename);

			if (file.isFile()) {

				url = file.toURI().toURL();
				treatment = 1;

			} else {

				url = new URL(filename);
				treatment = 2;
			}

											err=2;			
			InputStream input = TikaInputStream.get(url, metadata);

											err=3;
			ContentHandler handler = new BodyContentHandler(outputstream);

											err=4;
			parser.parse(input, handler, metadata, context);

											err=5;
			TikaConfig config = TikaConfig.getDefaultConfig();
			Detector detector = config.getDetector();
			
											err=6;
			TikaInputStream stream = TikaInputStream.get(input);

											err=7;
			Metadata metadata = new Metadata();
			metadata.add(Metadata.RESOURCE_NAME_KEY, filename);
			MediaType mediaType = detector.detect(stream, metadata);

			mimeType = mediaType.getType() + "/" + mediaType.getSubtype();

											err=8;
			input.close();
			
											err=0;

		}catch(Exception e){
			System.err.println("\nSerious problem (Tika, stage:"+err+") in parsing the following file: "+
							   "filename : "+ filename+"\n\n");
			// e.printStackTrace() ;
		}
		
	}

	private void getString() {

		// Get the text into a String object

		extractedText = outputstream.toString();

		// Do whatever you want with this String object.

		// System.out.println(extractedText);

	}

	public String run() throws Exception {

		process(fileSourceUrl);

		getString();

		return extractedText;
		
	}

	public String getMeta() {
		
		String xStr="";
		
		xStr = prepareMetaDataAsXml() ;
		
		return xStr;
	}
	
	// ========================================================================
	
	private String prepareMetaDataAsXml() {
		
		String mkeystr,str,xStr="";
		ArrayList<String> metadataItemList;
		
		metadataItemList = listAvailableMetaDataFields(metadata) ;
		
		// System.out.println("metadata");
		
		xStr = "<metadata>\n";
		for (int i=0;i<metadataItemList.size();i++){
			mkeystr = metadataItemList.get(i);
			str = metadata.get(mkeystr);
			
			// System.out.println("  -  "+mkeystr+" : "+str);
			xStr = xStr + "<meta item=\""+(i+1)+"\" key=\""+mkeystr+"\" value=\""+str+"\" /> \n";
		}
		
		xStr = xStr + "\n</metadata>";
		
		return xStr;
	}
	
	private ArrayList<String> listAvailableMetaDataFields(Metadata metadata) {
	
		ArrayList<String> metadataItemList = new ArrayList<String> ();
		for (int i = 0; i < metadata.names().length; i++) {
		
			String name = metadata.names()[i];
			// System.out.println(name + " : " + metadata.get(name));

			metadataItemList.add(name);
		}
		
		return metadataItemList;
	}
	public String getMimeType() {
		
		return mimeType;
	}
	
	
	
	/* non-local sources
	 * 
	 InputStream input = new FileInputStream(new File(resourceLocation));
		ContentHandler textHandler = new BodyContentHandler();
		Metadata metadata = new Metadata();
		PDFParser parser = new PDFParser();
		parser.parse(input, textHandler, metadata);
		input.close();
		
		out.println("Title: " + metadata.get("title"));
		out.println("Author: " + metadata.get("Author"));
		out.println("content: " + textHandler.toString());

		// Instead of creating creating PDFPaser you can use Tika's AutoDetectParser to automatically process diff types of files

		Parser parser = new AutoDetectParser()

	 * 
	 *  OR
	 * 
	 HttpGet httpget = new HttpGet("http://url.here"); 
    HttpEntity entity = null;
    HttpClient client = new DefaultHttpClient();
    HttpResponse response = client.execute(httpget);
    entity = response.getEntity();
    if (entity != null) {
        InputStream instream = entity.getContent();
        BodyContentHandler handler = new BodyContentHandler();
        Metadata metadata = new Metadata();
        Parser parser = new AutoDetectParser();
        parser.parse( instream, handler, metadata, new ParseContext());
        String plainText = handler.toString();
        FileWriter writer = new FileWriter( "/scratch/cache/output.txt");
        writer.write( plainText );
        writer.close();
        System.out.println( "done");
    }
 
	  
	 */

}
